package com.xdf.ecommerce.service.hystrix;

import com.netflix.hystrix.*;
import com.xdf.ecommerce.service.NacosClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 通过编程的方式实现 Hystrix 容错、降级
 * 不要作为 Bean ，成员变量要传入参数，无法使用自动注入
 * @author chanchaw
 * @create 2025-10-30 9:06
 */
@Slf4j
public class NacosClientHystrixCommand extends HystrixCommand<List<ServiceInstance>> {
    private final NacosClientService nacosClientService;
    private final String serviceId;

    public NacosClientHystrixCommand(NacosClientService nacosClientService,String serviceId) {
        // 下面的配置相当于 UseHystrixCommandAnnotation.getNacosClientInfo 上使用的注解
        super(
                Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("NacosClientService"))
                        .andCommandKey(HystrixCommandKey.Factory.asKey("NacosClientHystrixCommand"))
                        .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("NacosClientPool"))
                        // 线程池配置
                        .andCommandPropertiesDefaults(
                                HystrixCommandProperties.Setter()
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)// 线程池隔离策略
                                .withFallbackEnabled(true)// 开启降级策略
                                .withCircuitBreakerEnabled(true) // 开启熔断策略
                        )
        );
        this.nacosClientService = nacosClientService;
        this.serviceId = serviceId;
    }

    @Override
    protected List<ServiceInstance> run() throws Exception {
        log.info("通过编程方式实现 Hystrix 容错、降级，开始获取服务实例，线程名称：[{}]，即将查询获取服务：[{}]", Thread.currentThread().getName(), this.serviceId);
        return nacosClientService.getNacosClientInfo(this.serviceId);
    }

    @Override
    protected List<ServiceInstance> getFallback() {
        log.warn("通过编程方式实现 Hystrix 容错、降级测试中进入降级方法中，即将返回空集合。当前线程名称：[{}]，目标是获取服务 [{}] 的实例", Thread.currentThread().getName(),this.serviceId);
        return Collections.emptyList();
    }
}
